package com.example.service.impl;

import com.example.config.ClientConfig;
import com.example.model.bo.LoginInfo;
import com.example.service.LoginService;
import com.example.utils.ContractAddressManager;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.util.*;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {
    public static final String RegisterAndFileStoreABI = com.example.utils.IOUtil.readResourceAsString("abi/RegisterAndFileStore.abi");
    public static final String UserRegistryABI = com.example.utils.IOUtil.readResourceAsString("abi/UserRegistry.abi");

    // client 当前版本没有初始化 keypair
    @Autowired
    private Client client;

    AssembleTransactionProcessor txProcessor;

    @PostConstruct
    public void init() throws Exception {
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
    }

    @Override
    public Map<String, String> login(LoginInfo loginInfo) {
        Map<String, String> dic = new HashMap<>();
        String userName = loginInfo.getUserName();
        String password = loginInfo.getPassword();

        String keyfile = ClientConfig.account_keyfile_path + userName + ".p12";
        File file = new File(keyfile);
        if (!file.exists()) {
            dic.put("state", "不存在该用户");
        } else {
            try {
                // 从文件中解密并读取出公私钥
                ClientConfig.account_username = userName;
                ClientConfig.account_password = password;
                ClientConfig.account_keyfile = userName + ".p12";
                boolean flag = AccountManager.loadP12Account(client, ClientConfig.account_keyfile_path + ClientConfig.account_keyfile, password);
                if (!flag) {
                    dic.put("state", "用户名或密码错误");
                    return dic;
                }
                String address = client.getCryptoSuite().getCryptoKeyPair().getAddress();
//                System.out.println(client.getCryptoSuite().getCryptoKeyPair().getHexPrivateKey());
//                System.out.println(client.getCryptoSuite().getCryptoKeyPair().getHexPublicKey());
//                System.out.println("account_address:" + address);
                ClientConfig.account_address = address;
                dic.put("state", "success");
                dic.put("address", address);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return dic;
    }


    @Override
    public Map<String, String> register(LoginInfo loginInfo) throws Exception {
        String userName = loginInfo.getUserName();
        String password = loginInfo.getPassword();
        boolean type = loginInfo.isLoginType();

        // 检查用户名对应的 .p12 文件是否已经存在
        File p12File = new File(ClientConfig.account_keyfile_path + userName + ".p12");
        if (p12File.exists()) {
            // 如果文件存在，返回注册失败的消息
            Map<String, String> dic = new HashMap<>();
            dic.put("state", "success");
            log.info("用户已注册,userName:{}", userName);
            return dic;
        }


        // 创建非国密类型的CryptoSuite
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 随机生成非国密公私钥对
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        // 获取账户地址
        String address = cryptoKeyPair.getAddress();

        File keyStoreDir = new File(ClientConfig.account_keyfile_path);
        if (!keyStoreDir.exists()) {
            keyStoreDir.mkdirs();
        }
        AccountManager.saveAccountWithP12(cryptoKeyPair, ClientConfig.account_keyfile_path + userName + ".p12", password);
        new File(ClientConfig.account_keyfile_path + userName + ".p12.pub").delete();

        Map<String, String> dic = new HashMap<>();
        AccountManager.loadP12Account(client, ClientConfig.account_keyfile_path + userName + ".p12", password);
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
        //智能合约函数对应的参数列表
        List<Object> args = new ArrayList<>();
        Collections.addAll(args, userName, client.getCryptoSuite().getCryptoKeyPair().getHexPublicKey());
        String UserRegistryAddress = ContractAddressManager.getAddressFromContractNote("UserRegistry");
        this.txProcessor.sendTransactionAndGetResponse(UserRegistryAddress, UserRegistryABI, "registerUser", args);
        //添加参数信息
        args = new ArrayList<>(Arrays.asList(address, userName, type));
        String RegisterAndFileStoreAddress = ContractAddressManager.getAddressFromContractNote("RegisterAndFileStore");
        TransactionResponse txResp = this.txProcessor.sendTransactionAndGetResponse(RegisterAndFileStoreAddress, RegisterAndFileStoreABI, "register", args);
        TransactionReceipt txReceipt = txResp.getTransactionReceipt();
        if (!Objects.equals(txReceipt.getOutput(), "0x0000000000000000000000000000000000000000000000000000000000000000")) {
            dic.put("state", "系统异常");
        }
        dic.put("state", "success");
        dic.put("address", address);
        return dic;
    }
}
